Skip to content

feat: Azure OpenAI provider using @ai-sdk/azure#11144

Draft
roomote[bot] wants to merge 20 commits intomainfrom
feature/azure-ai-sdk-migration
Draft

feat: Azure OpenAI provider using @ai-sdk/azure#11144
roomote[bot] wants to merge 20 commits intomainfrom
feature/azure-ai-sdk-migration

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Feb 1, 2026

Summary

New Azure OpenAI provider built on @ai-sdk/azure v3.x (AI SDK v6). Replaces the legacy Azure path in the OpenAI handler with a dedicated provider using the modern Vercel AI SDK.

image

Provider Architecture

  • Uses createAzure() from @ai-sdk/azure with useDeploymentBasedUrls: true for Azure deployment-scoped endpoints
  • Defaults to the Responses API (AI SDK v6 standard) — compatible with gpt-4o, gpt-4.1, gpt-5.x, o3, o4-mini
  • API version defaults to 2025-04-01-preview (required for Responses API support)
  • Supports openai.azure.com, cognitiveservices.azure.com, and services.ai.azure.com endpoints

Settings UX

  • Azure Endpoint — accepts a base endpoint URL OR a full deployment URL (auto-extracts endpoint + deployment name)
  • Azure Deployment Name — the user's deployment name (may differ from the model name)
  • Azure API Key — optional (supports managed identity when omitted)
  • Azure API Version — hidden in Welcome view, defaults to 2025-04-01-preview
  • Model dropdown — 26 Azure OpenAI models for capability lookup (context window, pricing, reasoning support)
  • Default model: gpt-5.2 with medium reasoning effort

URL Auto-Parser

Users can paste a full Azure deployment URL like:

https://myresource.openai.azure.com/openai/deployments/gpt-4o/chat/completions?api-version=2025-04-01-preview

The endpoint field auto-extracts the base URL and deployment name. The API version from the URL is intentionally ignored (the default is always correct for the Responses API).

Bug Fixes (shared components)

  • Reasoning effort dropdown no longer shows blank for models with array-based supportsReasoningEffort (affects all providers with gpt-5.x models)

Test Coverage

  • 13 tests for URL parser (parseAzureUrl.spec.ts)
  • 15 tests for Azure handler (azure.spec.ts)

Files

New

  • webview-ui/src/components/settings/utils/parseAzureUrl.ts
  • webview-ui/src/components/settings/utils/__tests__/parseAzureUrl.spec.ts

Modified

  • src/api/providers/azure.ts — Azure handler using @ai-sdk/azure
  • webview-ui/src/components/settings/providers/Azure.tsx — Settings UI with auto-parser
  • webview-ui/src/components/settings/constants.ts — Azure models in provider map
  • webview-ui/src/components/settings/utils/providerModelConfig.ts — Default model config
  • webview-ui/src/components/settings/ThinkingBudget.tsx — Reasoning effort default fix
  • webview-ui/src/i18n/locales/en/settings.json — Updated labels/descriptions
  • packages/types/src/providers/azure.ts — Default model ID

@roomote
Copy link
Contributor Author

roomote bot commented Feb 1, 2026

Rooviewer Clock   See task

All previously flagged issues are resolved. No new issues found. The Azure OpenAI provider implementation correctly follows the established AI SDK migration pattern, has comprehensive test coverage, and complete UI integration.

  • Missing isAiSdkProvider() override in Azure handler - needed for reasoning block preservation
  • Incomplete rename: constants.ts and providerModelConfig.ts still say "Azure AI Foundry" instead of "Azure OpenAI"
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

@daniel-lxs daniel-lxs marked this pull request as ready for review February 2, 2026 02:36
@daniel-lxs daniel-lxs requested review from cte, jr and mrubens as code owners February 2, 2026 02:36
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. Enhancement New feature or request labels Feb 2, 2026
@roomote
Copy link
Contributor Author

roomote bot commented Feb 2, 2026

Rooviewer Clock   See task on Roo Cloud

Review complete. No issues found.

The Azure OpenAI provider implementation correctly follows the established AI SDK migration pattern (DeepSeek, Groq, Fireworks). The handler properly integrates with @ai-sdk/azure, includes comprehensive test coverage, and has complete UI integration with translations for all locales.

  • No bugs or issues identified

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Feb 2, 2026
@daniel-lxs daniel-lxs marked this pull request as draft February 2, 2026 17:29
@hannesrudolph hannesrudolph force-pushed the feature/azure-ai-sdk-migration branch from 25d2476 to 1c3437f Compare February 3, 2026 22:43
@hannesrudolph hannesrudolph changed the title feat: Add dedicated Azure OpenAI provider using @ai-sdk/azure package (EXT-709) feat(azure): Azure AI Foundry provider with model metadata and model picker Feb 5, 2026
@hannesrudolph hannesrudolph force-pushed the feature/azure-ai-sdk-migration branch from d00536b to e30e3c1 Compare February 5, 2026 22:38
@hannesrudolph hannesrudolph changed the title feat(azure): Azure AI Foundry provider with model metadata and model picker feat(azure): Azure OpenAI provider with model metadata and model picker Feb 6, 2026
@hannesrudolph hannesrudolph force-pushed the feature/azure-ai-sdk-migration branch from 421699d to 8c31b80 Compare February 6, 2026 22:41
Copy link
Contributor Author

@roomote roomote bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review: feat(azure): Azure OpenAI provider with model metadata and model picker

Summary

Solid, well-structured PR that adds Azure OpenAI as a first-class provider. The implementation follows established patterns from other AI SDK providers (DeepSeek, Cerebras, etc.), with proper separation between types, API handler, and UI components. All tests pass (15 Azure handler tests, 13 parseAzureUrl tests, validate + checkExistApiConfig tests all green), and TypeScript compiles without errors.

What works well

  • Pattern consistency: AzureHandler mirrors the existing DeepSeekHandler structure almost 1:1 (imports, constructor, getModel, getLanguageModel, processUsageMetrics, getMaxOutputTokens, createMessage, completePrompt, isAiSdkProvider). Easy to review because the pattern is familiar.
  • Deployment vs. model separation: Clean design where azureDeploymentName is the API routing key and apiModelId is the capability lookup key. The fallback chain in getModel() (azureModels[modelId] -> azureModels[deploymentId] -> azureDefaultModelInfo) handles the case where the deployment name matches a known model.
  • URL auto-parser: Clean regex-based parser that extracts baseUrl and deploymentName from a pasted full Azure URL. Intentionally ignoring api-version to use the app default is a good design choice.
  • Validation UX: Skipping errors on fresh provider selection (all fields empty) prevents annoying immediate errors when switching providers.
  • Comprehensive localization: All 18 locales updated consistently.
  • Test coverage: Good coverage of handler constructor, streaming, tool calls, errors, cache metrics via providerMetadata, and the URL parser edge cases.

Minor suggestions (non-blocking)

  1. azureApiKey empty string handling (src/api/providers/azure.ts:45): The baseURL parameter uses options.azureBaseUrl || undefined to convert empty string to undefined, but apiKey does not. If azureApiKey is "", it would be passed through as-is. Consider apiKey: options.azureApiKey || undefined for symmetry, so the SDK can properly fall back to env vars when no key is provided.

  2. checkExistKey loose check (src/shared/checkExistApiConfig.ts:12): !!(config.azureBaseUrl || config.azureDeploymentName || config.azureApiKey) means setting only a deployment name (without a base URL) returns true ("configured"), even though it cannot make API calls. The downstream validation in validateModelsAndKeysProvided catches this, but it is worth noting that checkExistKey is used in other paths too (e.g., onboarding flow).

  3. getModel() called multiple times per request: In createMessage, getModel() runs via direct call (line 130), getLanguageModel() (line 131 -> 75), and getMaxOutputTokens() (line 146 -> 116). That is 3 invocations per streaming request, each re-computing model params. This is consistent with other providers (DeepSeek does the same), but if perf ever matters, caching the result per-request would be trivial.

  4. Test: useDeploymentBasedUrls not asserted: The createAzure mock does not verify that useDeploymentBasedUrls: true is passed in the constructor. Since this is a critical behavioral flag (it changes the URL routing), adding an assertion like expect(createAzure).toHaveBeenCalledWith(expect.objectContaining({ useDeploymentBasedUrls: true })) would be a nice addition.

Verdict

LGTM -- clean implementation that follows project patterns, comprehensive test coverage, and proper type integration. The suggestions above are all minor and non-blocking.

@hannesrudolph hannesrudolph changed the title feat(azure): Azure OpenAI provider with model metadata and model picker feat: Azure OpenAI provider using @ai-sdk/azure Feb 7, 2026
roomote and others added 7 commits February 6, 2026 19:51
- Add azureApiKey to SECRET_STATE_KEYS for proper configuration detection
- Add Azure validation case in validateModelsAndKeysProvided
- Add validation translations for azureResourceName and azureDeploymentName across all 18 locales

This fixes the issue where the Finish button does nothing when setting up Azure provider in the onboarding workflow.
…ndry

- Add static model metadata for 29 Azure models (from models.dev)
  with Roo-specific flags (reasoning, tools, verbosity) matching
  openAiNativeModels
- Add model picker dropdown to Azure provider settings for model
  capability detection (context window, max tokens, pricing)
- Rename provider label from 'Azure OpenAI' to 'Azure AI Foundry'
  across all 18 locales
- Make API key optional (supports Azure managed identity / Entra ID)
- Update default API version from 2024-08-01-preview to 2025-04-01-preview
- Fix maxOutputTokens validation (filter invalid values <= 0)
- Handler separates deployment name (API calls) from model ID
  (capability lookup) with azureDefaultModelInfo (gpt-4o) fallback
- Remove unhelpful 'Get Azure AI Foundry Access' button
- Prevent stale model IDs from other providers carrying over
- Suppress validation errors on fresh provider selection
hannesrudolph and others added 13 commits February 6, 2026 19:51
- Upgrade @ai-sdk/azure from ^2.0.6 to ^3.0.26
  - v3 defaults provider(id) to Responses API (works for all models)
  - v2 defaulted to Chat Completions, breaking codex models
- Add useDeploymentBasedUrls: true to createAzure()
  - Produces /deployments/{id}/{path} URLs (universally compatible)
  - Without it, SDK uses /v1/{path} which only works on AI Foundry resources
Expand azure model list from 27 (OpenAI-only) to 64 models with
tool_call support, including Claude, Cohere, DeepSeek, Grok, Kimi,
Llama, Mistral, Phi, and Model Router families.

All model metadata (pricing, context window, capabilities) sourced
from https://models.dev/api.json. Existing Roo-specific overrides
(includedTools, excludedTools, reasoningEffort, etc.) preserved.
Remove gpt-4 (8k) and gpt-4-32k (32k) — too small for agentic use.
62 models remain, all with tool_call support and ≥128k context.
- Fix baseURL empty string fallback (pass undefined instead of "" to let SDK use env vars)
- Add parseAzureUrl() utility that extracts endpoint, deployment name, and API version from a full Azure deployment URL
- Integrate auto-parser into Azure settings: pasting a full URL auto-fills all fields
- Rename "Base URL" to "Azure Endpoint" to match Azure portal terminology
- Improve field descriptions for deployment name and API version
- Add 13 tests for URL parser (all passing)
Pasted URLs often contain older API versions (e.g., 2024-05-01-preview) that
are incompatible with the Responses API. The parser now only extracts endpoint
and deployment name, letting the API version default to 2025-04-01-preview.
The API version field is an advanced option that 99% of users won't change.
Hide it in the onboarding Welcome view using the existing simplifySettings
pattern (matches OpenRouter's approach for custom base URL).
Update default Azure model from gpt-4o to gpt-5.2 and ensure reasoning
effort defaults are properly configured.
Models with supportsReasoningEffort as an array (e.g., gpt-5.2) and no
requiredReasoningEffort would show a blank dropdown because the default
fell to 'disable' which wasn't in the available options. Now uses the
model's declared reasoningEffort as the default.
- Handler: createAzure constructor args, dual-ID getModel lookup,
  processUsageMetrics, getMaxOutputTokens, reasoning events,
  tool-call ignoring, completePrompt error propagation,
  provider metadata key mismatch
- Validation: 4 Azure branches in validate.spec.ts
- Config: 4 Azure cases in checkExistApiConfig.spec.ts
- Types: 6 model definition correctness tests, 3 Zod schema round-trips
- URL parser: 3 additional edge cases

Total: 105 tests across 6 suites (was 70)
@hannesrudolph hannesrudolph force-pushed the feature/azure-ai-sdk-migration branch from 2026ae7 to d7be2b9 Compare February 7, 2026 02:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request lgtm This PR has been approved by a maintainer size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants